package com.star.uc.infras.utils;

import com.star.common.core.context.SpringContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 滑动窗口限速器
 *
 * @author zhouhengzhe
 */
@Component
public class SlideWindowRateLimitUtils {

    /**
     * 将窗口值自增,并检测是否超过最大限制
     *
     * @param key                 窗口KEy
     * @param maxLimit            最大限制值
     * @param windowSizeOfSeconds 滑动窗口长度,以秒为单位
     * @return 返回值小于0则表示为未超过限制, 大于0表示超过最大值限制, 并表示窗口剩余时间
     */
    public Long isLimit(String key, long maxLimit, long windowSizeOfSeconds) {
        boolean success = Boolean.TRUE.equals(SpringContext.getBean(StringRedisTemplate.class)
                .opsForValue()
                .setIfAbsent(key, "1", windowSizeOfSeconds, TimeUnit.SECONDS));
        if (!success) {
            Long val = SpringContext.getBean(StringRedisTemplate.class).opsForValue().increment(key);
            if (Objects.nonNull(val) && val > maxLimit) {
                return SpringContext.getBean(StringRedisTemplate.class).opsForValue().getOperations().getExpire(key);
            }
        }
        return -1L;
    }
}
